package com.example.g7640.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.g7640.builder.ResultBuilder;
import com.example.g7640.dto.*;
import com.example.g7640.dto.common.PageResult;
import com.example.g7640.entity.Customer;
import com.example.g7640.entity.Vendor;
import com.example.g7640.enums.TrueFalseEnum;
import com.example.g7640.enums.UserType;
import com.example.g7640.exception.BizException;
import com.example.g7640.mapper.CustomerMapper;
import com.example.g7640.service.CustomerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.g7640.service.UserService;
import com.example.g7640.util.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author  
 * @since 2024-03-18
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService, UserService {

    @Resource
    CustomerMapper customerMapper;

    @Override
    public SessionDto login(LoginDto loginDto) {
        Customer customerDb = this.queryByAccount(loginDto.getAccount());
        if(customerDb == null){
            throw new BizException("admin is not exist");
        }
        String dbPassword = customerDb.getPassword();
        if(!dbPassword.equals(loginDto.getPassword())){
            throw new BizException("password is wrong");
        }

        SessionDto sessionDto = new SessionDto();
        sessionDto.setId(customerDb.getId());
        sessionDto.setAccount(customerDb.getAccount());
        sessionDto.setName(customerDb.getName());
        sessionDto.setType(UserType.customer.getIndex());
        return sessionDto;
    }

    @Override
    public void register(RegistDto registDto) {
        Customer customerDb = this.queryByAccount(registDto.getAccount());
        if(customerDb != null){
            throw new BizException("This customer account is already exist");
        }
        LocalDateTime localDateTime = LocalDateTime.now();
        Customer customer = new Customer();
        BeanUtils.copyProperties(registDto, customer);
        customer.setDeleted(TrueFalseEnum.FALSE.getCode());
        customer.setCreatedAt(localDateTime);
        customer.setUpdatedAt(localDateTime);
        customerMapper.insert(customer);
    }

    @Override
    public Integer getType() {
        return UserType.customer.getIndex();
    }

    @Override
    public void changePassword(UserChangePasswordDto u) {
        RoleCheckUtil.checkCustomer();
        Integer id = SessionLocal.getLoginId();
        Customer customerDb = customerMapper.selectById(id);
        if(customerDb == null){
            throw new BizException("customer is not exist");
        }
        String oldPassword = PasswordUtil.encodePassword(u.getOldPass());
        String newPassword = PasswordUtil.encodePassword(u.getNewPass());
        if(!Objects.equals(oldPassword,customerDb.getPassword())){
            throw new BizException("Old password wrong");
        }
        customerDb.setPassword(newPassword);
        customerDb.setUpdatedAt(LocalDateTime.now());
        customerMapper.updateById(customerDb);
    }

    private Customer queryByAccount(String account){
        LambdaQueryWrapper<Customer> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Customer::getAccount,account);
        wrapper.eq(Customer::getDeleted,TrueFalseEnum.FALSE.getCode());
        List<Customer> customers = customerMapper.selectList(wrapper);
        return CollectionUtil.getFirstObj(customers);
    }

    @Override
    public CustomerDto getCustomerDtoById(Integer id) {
        RoleCheckUtil.check(UserType.admin,UserType.vendor);
        Customer customer = customerMapper.selectById(id);
        return BaseConvertor.convert(customer,CustomerDto.class);
    }

    @Override
    public PageResult<List<CustomerDto>> query(CustomerQuery customerQuery) {
        RoleCheckUtil.checkAdmin();
        LambdaQueryWrapper<Customer> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(Customer::getId, customerQuery.getId());
        if(customerQuery.getName() != null) {
            wrapper.like(Customer::getName,customerQuery.getName());
        }
        if(customerQuery.getAccount() != null) {
            wrapper.like(Customer::getAccount,customerQuery.getAccount());
        }
        IPage iPage = customerMapper.selectPage(PageUtil.pageToMybatisPage(customerQuery), wrapper);
        return ResultBuilder.buildPageSuccess((int)iPage.getTotal(),(int)iPage.getCurrent(),(int)iPage.getSize(),BaseConvertor.convertList(iPage.getRecords(),CustomerDto.class));
    }

    @Override
    public void updatePassword(ChangePasswordDto changePasswordDto) {
        RoleCheckUtil.checkCustomer();
        Integer id = SessionLocal.getLoginId();
        Customer customerDb = customerMapper.selectById(id);
        if(customerDb == null){
            throw new BizException("customer is not exist");
        }
        String oldPassword = PasswordUtil.encodePassword(changePasswordDto.getOldPwd());
        String newPassword = PasswordUtil.encodePassword(changePasswordDto.getNewPwd());
        if(!Objects.equals(oldPassword,customerDb.getPassword())){
            throw new BizException("Old password wrong");
        }
        customerDb.setPassword(newPassword);
        customerDb.setUpdatedAt(LocalDateTime.now());
        customerMapper.updateById(customerDb);
    }

    @Override
    public void resetPassword(CustomerDto customerDto) {
        RoleCheckUtil.checkAdmin();
        Customer customerDb = customerMapper.selectById(customerDto.getId());
        if(customerDb == null){
            throw new BizException("customer is not exist");
        }
        customerDb.setPassword(PasswordUtil.encodePassword(customerDto.getPassword()));
        customerDb.setUpdatedAt(LocalDateTime.now());
        customerMapper.updateById(customerDb);
    }

    @Override
    public void deleteCustomer(Integer id) {
        RoleCheckUtil.checkAdmin();
        Customer customerDb = customerMapper.selectById(id);
        if(customerDb == null){
            throw new BizException("customer is not exist");
        }
        customerDb.setDeleted(TrueFalseEnum.TRUE.getCode());
        customerDb.setUpdatedAt(LocalDateTime.now());
        customerMapper.updateById(customerDb);
    }
}
